package beans;

import entidades.Processo;
import entidades.Usuario;
import excessoes.DAOException;
import excessoes.FabricaDAOException;
import excessoes.UtilException;
import fabricas.PropertiesFabrica;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;
import rn.ProcessoRN;
import util.ContextoUtil;
import util.FacesUtil;

/**
 *
 * @author Marcelo Gomes Neto
 */
/*
@ViewScoped = Instancia do bean é criada e mantida enquanto o usuário estiver na página (por exemplo, com os manipuladores de eventos ou Ajax). Deve implementar Serializable
@SessionScoped = Criado um por sessão de cada usuário.
@ApplicationScoped = Criado um para toda a aplicação.
@RequestScoped = Escopo padrão. É criado a cada requisição. 
 */
@ManagedBean(name="cadastroProcessoBean")
@ViewScoped
public class CadastroProcessoBean implements Serializable 
{
    private static final long serialVersionUID = -7251860446166012165L;
    private final String ARQUIVO = FacesUtil.getServletContext().getRealPath("/WEB-INF/sispac.properties");
    private Properties propriedades;
    private Processo processo = new Processo();
    private StreamedContent arquivoRetornoPAG;
    private int tipoRelatorio;  
    private Integer unidadeSelecionada;
    private String seqNup;
    private String siglaNup;
    private String anoNup;
    private UploadedFile uploadArquivo;
    private String nomeArquivoSelecionado;
    private String uf = "AC";
    private List<SelectItem> ufs = new ArrayList<>();
    private String nupProcHap;
    private Boolean isProcesso = true;

    public CadastroProcessoBean() 
    {
        try 
        {
            this.propriedades = PropertiesFabrica.lePropertiesJsf(ARQUIVO);
            this.seqNup = this.propriedades.getProperty("SEQUENCIALNUP").trim();
            this.siglaNup = this.propriedades.getProperty("SIGLANUP").trim();
            this.anoNup = this.propriedades.getProperty("ANONUP").trim();

            if(this.isProcesso == true) {
                this.setNupProcHap(this.seqNup.concat("/").concat(this.siglaNup).concat("/").concat(this.anoNup));
            }
            else {
                this.setNupProcHap(this.seqNup.concat("/").concat(this.uf).concat("-").concat(this.siglaNup).concat("/").concat(this.anoNup));
            }
        }
        catch (FabricaDAOException ex) {
        }
    }

    public String salvar() throws DAOException, Exception, Throwable
    {
        try 
        {
            ContextoBean contextoBean = ContextoUtil.getContextoBean();
            Usuario usuario = contextoBean.getUsuarioLogado();
            ProcessoRN processoRN = new ProcessoRN();

            if (this.nomeArquivoSelecionado == null || this.nomeArquivoSelecionado.equals("")) {
                this.processo.setArquivo(false);
            }   
            else {
                this.processo.setArquivo(true);
            }
            
            if(this.isProcesso == true) {
                this.processo.setHapvida(false);
            }
            else {
                this.processo.setHapvida(true);
            }
            this.processo.setPag(this.nupProcHap);
            processoRN.salvarProcesso(this.processo, usuario);
            
            Processo contemPag = processoRN.carregarProcessoPorPag(this.processo.getPag());
            Processo contemPam = processoRN.carregarProcessoPorPam(this.processo.getPam());
            if (contemPam != null || contemPag != null)
            {
                Integer seq = Integer.valueOf(this.seqNup)+1;
                this.propriedades.setProperty("SEQUENCIALNUP", String.valueOf(seq));
                PropertiesFabrica.salvaPropertiesJsf(this.propriedades, ARQUIVO);
                this.setNupProcHap(this.nupProcHap);
                this.setNomeArquivoSelecionado(null);
                this.processo = new Processo();
            }
        }
         catch (DAOException | NumberFormatException | FabricaDAOException ex) {
            System.out.println("O erro é: "+ex.toString());
        }
        return "/restrito/processo/cadastrar/cadastro_processo.xhtml"; 
    }
    
    public String fileUploadAction(FileUploadEvent event) throws IOException, NotSerializableException, Exception 
    {
        ProcessoRN processoRN = new ProcessoRN();
        Integer id = processoRN.retornaUltimoID()+1;

        Integer idArq = this.processo.getIdprocesso();
        String local = null;
        //System.out.println("O IdArq é: "+idArq);
        
        if (idArq != null) {
            this.setNomeArquivoSelecionado(event.getFile().getFileName());
            local = FacesUtil.getServletContext().getRealPath("/downloads/"+idArq+".pdf");
        }
        else {
            this.setNomeArquivoSelecionado(event.getFile().getFileName());
            local = FacesUtil.getServletContext().getRealPath("/downloads/"+id+".pdf");
        }
        
        //Cria um arquivo UploadFile, para receber o arquivo do evento
        this.uploadArquivo = event.getFile();
        InputStream in = new BufferedInputStream(this.uploadArquivo.getInputstream());
        //copiar para pasta do projeto
        File file = new File(local); 
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream(file);
                
            while(in.available() != 0){
                fout.write(in.read());
            }
            fout.close();
         }
        catch (IOException io){
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não foi possível salvar o arquivo!", ""));
        }
        return null;
    }

    public void setArquivoRetornoPAG(StreamedContent arquivoRetornoPAG) {
        this.arquivoRetornoPAG = arquivoRetornoPAG;
    }
    
    public StreamedContent getArquivoRetornoPAG() throws NotSerializableException, UtilException
    {
        try
        {
            Integer id = this.processo.getIdprocesso();
            String local = FacesUtil.getServletContext().getRealPath("/downloads/"+id+".pdf");
            InputStream conteudoRelatorio = new FileInputStream(local);
            this.arquivoRetornoPAG = new DefaultStreamedContent(conteudoRelatorio, "application/pdf", "PAG_"+id+".pdf");
        }
        catch (FileNotFoundException e) {
            throw new UtilException("Arquivo não encontrado: "+e.getMessage());
	}
        return this.arquivoRetornoPAG;
    }
    
    public int getTipoRelatorio() {
        return tipoRelatorio;
    }

    public void setTipoRelatorio(int tipoRelatorio) {
        this.tipoRelatorio = tipoRelatorio;
    }

    public Integer getUnidadeSelecionada() {
        return unidadeSelecionada;
    }

    public void setUnidadeSelecionada(Integer unidadeSelecionada) {
        this.unidadeSelecionada = unidadeSelecionada;
    }

    public UploadedFile getUploadArquivo() {
        return uploadArquivo;
    }

    public void setUploadArquivo(UploadedFile uploadArquivo) {
        this.uploadArquivo = uploadArquivo;
    }

    public String getNomeArquivoSelecionado() {
        return nomeArquivoSelecionado;
    }

    public void setNomeArquivoSelecionado(String nomeArquivoSelecionado) {
        this.nomeArquivoSelecionado = nomeArquivoSelecionado;
    }
    
        public Processo getProcesso() {
        return processo;
    }

    public void setProcesso(Processo processo) {
        this.processo = processo;
    }

    public Properties getPropriedades() {
        return propriedades;
    }

    public void setPropriedades(Properties propriedades) {
        this.propriedades = propriedades;
    }

    public String getSeqNup() {
        return this.propriedades.getProperty("SEQUENCIALNUP").trim();
    }

    public void setSeqNup(String seqNup) {
        this.seqNup = seqNup;
    }

    public String getSiglaNup() {
        return this.propriedades.getProperty("SIGLANUP");
    }

    public void setSiglaNup(String siglaNup) {
        this.siglaNup = siglaNup;
    }

    public String getAnoNup() {
        return this.propriedades.getProperty("ANONUP");
    }

    public void setAnoNup(String anoNup) {
        this.anoNup = anoNup;
    }

    public Boolean getIsProcesso() {
        return isProcesso;
    }

    public void setIsProcesso(Boolean isProcesso) {
        this.isProcesso = isProcesso;
    }

    public String getUf() {
        return uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    public List<SelectItem> getUfs() 
    {
        this.ufs = new ArrayList<>();
        this.ufs.add(new SelectItem("AC", "AC"));
        this.ufs.add(new SelectItem("AL", "AL"));
        this.ufs.add(new SelectItem("AM", "AM"));
        this.ufs.add(new SelectItem("AP", "AP"));
        this.ufs.add(new SelectItem("BA", "BA"));
        this.ufs.add(new SelectItem("CE", "CE"));
        this.ufs.add(new SelectItem("DF", "DF"));
        this.ufs.add(new SelectItem("ES", "ES"));
        this.ufs.add(new SelectItem("GO", "GO"));
        this.ufs.add(new SelectItem("MA", "MA"));
        this.ufs.add(new SelectItem("MG", "MG"));
        this.ufs.add(new SelectItem("MS", "MS"));
        this.ufs.add(new SelectItem("MT", "MT"));
        this.ufs.add(new SelectItem("PA", "PA"));
        this.ufs.add(new SelectItem("PB", "PB"));
        this.ufs.add(new SelectItem("PE", "PE"));
        this.ufs.add(new SelectItem("PI", "PI"));
        this.ufs.add(new SelectItem("PR", "PR"));
        this.ufs.add(new SelectItem("RJ", "RJ"));
        this.ufs.add(new SelectItem("RN", "RN"));
        this.ufs.add(new SelectItem("RO", "RO"));
        this.ufs.add(new SelectItem("RR", "RR"));
        this.ufs.add(new SelectItem("RS", "RS"));
        this.ufs.add(new SelectItem("SC", "SC"));
        this.ufs.add(new SelectItem("SE", "SE"));
        this.ufs.add(new SelectItem("SP", "SP"));
        this.ufs.add(new SelectItem("TO", "TO"));
        return ufs;
    }

    public void setUfs(List<SelectItem> ufs) {
        this.ufs = ufs;
    }

    public void atualizaNupPorUf(ValueChangeEvent event) 
    {
        Object valor = event.getNewValue(); 
        this.uf = (String)valor; 
        this.setUf(this.uf);
        this.setNupProcHap(this.seqNup.concat("/").concat(this.uf).concat("-").concat(this.siglaNup).concat("/").concat(this.anoNup));
    }

    public void atualizaNupRadio(ValueChangeEvent event) 
    {
        Object valor = event.getNewValue(); 
        this.isProcesso = (Boolean) valor;
        this.setIsProcesso(this.isProcesso);
        if(this.isProcesso == true) {
            this.setNupProcHap(this.seqNup.concat("/").concat(this.siglaNup).concat("/").concat(this.anoNup));
        }
        else {
            this.setNupProcHap(this.seqNup.concat("/").concat(this.uf).concat("-").concat(this.siglaNup).concat("/").concat(this.anoNup));
        }
    }
    
    public final String getNupProcHap() {
        return nupProcHap;
    }

    public final void setNupProcHap(String nupProcHap) {
        this.nupProcHap = nupProcHap;
    }
}